package com.taotao.wechat.util;

import com.rop.Constants;
import com.rop.client.CompositeResponse;
import com.taotao.admin.MyRopClient;
import com.taotao.rop.database.Constant;
import com.taotao.rop.database.domain.OtherTel;
import com.taotao.rop.database.domain.PlayGame;
import com.taotao.rop.database.domain.Tel;
import com.taotao.rop.database.domain.WechatUser;
import com.taotao.rop.response.BaseResponse;
import com.taotao.wechat.GameConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.regex.Pattern;

public class ValidateUtil {
    private static final Logger logger = LoggerFactory.getLogger(ValidateUtil.class);
    private static final Pattern isTel = Pattern.compile("^(13|14|15|16|17|18|19)\\d{9}$");
    public static final int NO_MEMBER_COUNT = -1;
    public static final int NO_COUNT = 0;
    public static final int NORMAL_COUNT = 1;
    public static final int MEMBER_COUNT = 2;

    private static List<String> cityList = Arrays.asList("阿拉善", "巴彦淖尔", "包头", "赤峰", "鄂尔多斯", "呼和浩特", "呼伦贝尔", "通辽", "乌海", "乌兰察布", "锡林郭勒", "兴安");

    public static boolean isTelphone(String mobile)
    {
        return isTel.matcher(mobile).matches();
    }

    /**
     * tel手机号是否是内蒙古移动号码
     * @return 0:是； 1：否； -1：未识别；-2不是手机号码；-3系统异常
     */
    public static synchronized int isYiDong(String tel) {
        if (!isTelphone(tel)) {
            return -2;
        }

        Tel condition = new Tel();
        int noSegment = Integer.parseInt(tel.trim().substring(0, 7));
        condition.setNoSegment(noSegment);

        CompositeResponse<BaseResponse> response = MyRopClient.getRopClient("").buildClientRequest()
                .post(condition, BaseResponse.class, "tel.list", "1.0");
        if (response.isSuccessful()) {
            BaseResponse baseResponse = response.getSuccessResponse();
            if (baseResponse.getSuccess()) {
                List<LinkedHashMap<String, Object>> dataMap = (List<LinkedHashMap<String, Object>>) baseResponse.getData();
                if (dataMap != null && dataMap.size() > 0) {
                    LinkedHashMap<String, Object> data = dataMap.get(0);
                    String area = (String) data.get("area");
                    String numType = (String) data.get("numType");
                    if ("移动".equalsIgnoreCase(numType)) {
                        if (area != null) {
                            area = area.trim().replace("内蒙古", "");
                            if (cityList.contains(area)) {
                                return 0;
                            }
                        }
                    }
                    return 1;
                } else {
                    //tel数据库中没有这个号码，录入othertel数据库等待审核
                    OtherTel otherTel = new OtherTel(noSegment, tel.trim());
                    MyRopClient.getRopClient("").buildClientRequest()
                            .post(otherTel, BaseResponse.class, "otherTel.insert", "1.0");
                    return -1;
                }
            }
        }
        return -3;
    }

    /**
     * tel手机号是否是内蒙古指定city的移动号码
     * @return 0:是； 1：否； -1：未识别；-2不是手机号码；-3系统异常
     */
    public static synchronized int isYiDong(String tel, String city) {
        if (!isTelphone(tel)) {
            return -2;
        }

        Tel condition = new Tel();
        int noSegment = Integer.parseInt(tel.trim().substring(0, 7));
        condition.setNoSegment(noSegment);

        CompositeResponse<BaseResponse> response = MyRopClient.getRopClient("").buildClientRequest()
                .post(condition, BaseResponse.class, "tel.list", "1.0");
        if (response.isSuccessful()) {
            BaseResponse baseResponse = response.getSuccessResponse();
            if (baseResponse.getSuccess()) {
                List<LinkedHashMap<String, Object>> dataMap = (List<LinkedHashMap<String, Object>>) baseResponse.getData();
                if (dataMap != null && dataMap.size() > 0) {
                    LinkedHashMap<String, Object> data = dataMap.get(0);
                    String area = (String) data.get("area");
                    String numType = (String) data.get("numType");
                    if ("移动".equalsIgnoreCase(numType)) {
                        if (area != null) {
                            area = area.trim().replace("内蒙古", "");
                            if (city.contains(area)) {
                                return 0;
                            }
                        }
                    }
                    return 1;
                } else {
                    //tel数据库中没有这个号码，录入othertel数据库等待审核
                    OtherTel otherTel = new OtherTel(noSegment, tel.trim());
                    MyRopClient.getRopClient("").buildClientRequest()
                            .post(otherTel, BaseResponse.class, "otherTel.insert", "1.0");
                    return -1;
                }
            }
        }
        return -3;
    }

    /**
     * tel手机号是否是内蒙古指定cityList的移动号码
     * @return 0:是； 1：否； -1：未识别；-2不是手机号码；-3系统异常
     */
    public static synchronized int isYiDong(String tel, List<String> cityList) {
        if (!isTelphone(tel)) {
            return -2;
        }

        Tel condition = new Tel();
        int noSegment = Integer.parseInt(tel.trim().substring(0, 7));
        condition.setNoSegment(noSegment);

        CompositeResponse<BaseResponse> response = MyRopClient.getRopClient("").buildClientRequest()
                .post(condition, BaseResponse.class, "tel.list", "1.0");
        if (response.isSuccessful()) {
            BaseResponse baseResponse = response.getSuccessResponse();
            if (baseResponse.getSuccess()) {
                List<LinkedHashMap<String, Object>> dataMap = (List<LinkedHashMap<String, Object>>) baseResponse.getData();
                if (dataMap != null && dataMap.size() > 0) {
                    LinkedHashMap<String, Object> data = dataMap.get(0);
                    String area = (String) data.get("area");
                    String numType = (String) data.get("numType");
                    if ("移动".equalsIgnoreCase(numType)) {
                        if (area != null) {
                            area = area.trim().replace("内蒙古", "");
                            if (cityList.contains(area)) {
                                return 0;
                            }
                        }
                    }
                    return 1;
                } else {
                    //tel数据库中没有这个号码，录入othertel数据库等待审核
                    OtherTel otherTel = new OtherTel(noSegment, tel.trim());
                    MyRopClient.getRopClient("").buildClientRequest()
                            .post(otherTel, BaseResponse.class, "otherTel.insert", "1.0");
                    return -1;
                }
            }
        }
        return -3;
    }

    /**
     * 此appId平台的用户openId今天是否还有参加的次数
     * @return -1:会员次数没了； 0:正常次数没了；1：正常次数；2：会员次数
     */
    public static int hasJoinToday(String appId, String openId) {
        PlayGame condition = new PlayGame();
        condition.setAppId(appId);
        condition.setOpenId(openId);
        condition.setGameName(GameConstant.GAME_NICK_NAME);

        CompositeResponse<BaseResponse> response = MyRopClient.getRopClient("").buildClientRequest()
                .post(condition, BaseResponse.class, "playGame.getJoinCountToday", "1.0");
        if (response.isSuccessful()) {
            BaseResponse baseResponse = response.getSuccessResponse();
            if (baseResponse.getSuccess()) {
                int count = (Integer) baseResponse.getData();
                boolean joinCountOfMember = hasJoinCountOfMember(appId, openId, count, GameConstant.MAX_COUNT_OF_WECHAT_JOIN_MEMBER);
                if (count >= GameConstant.MAX_COUNT_OF_WECHAT_JOIN && count < GameConstant.MAX_COUNT_OF_WECHAT_JOIN_MEMBER){
                    if (joinCountOfMember) {
                        return MEMBER_COUNT;
                    }
                    return NO_MEMBER_COUNT;
                }

                if (count < GameConstant.MAX_COUNT_OF_WECHAT_JOIN){
                    return NORMAL_COUNT;
                }
            }
        }
        return NO_COUNT;
    }

    /**
     * 此appId平台的用户openId今天是否还有参加的次数
     * @return -1:会员次数没了； 0:正常次数没了；1：正常次数；2：会员次数
     */
    public static int hasJoinToday(String appId, String openId, String gameName,
                                   int maxWechatCount, int maxWechatMemberCount) {
        PlayGame condition = new PlayGame();
        condition.setAppId(appId);
        condition.setOpenId(openId);
        condition.setGameName(gameName);

        CompositeResponse<BaseResponse> response = MyRopClient.getRopClient("").buildClientRequest()
                .post(condition, BaseResponse.class, "playGame.getJoinCountToday", "1.0");
        if (response.isSuccessful()) {
            BaseResponse baseResponse = response.getSuccessResponse();
            if (baseResponse.getSuccess()) {
                int count = (Integer) baseResponse.getData();
                boolean joinCountOfMember = hasJoinCountOfMember(appId, openId, count, maxWechatCount);
                if (count >= maxWechatCount && count < maxWechatMemberCount){
                    if (joinCountOfMember) {
                        return MEMBER_COUNT;
                    }
                    return NO_MEMBER_COUNT;
                }

                if (count < maxWechatCount){
                    return NORMAL_COUNT;
                }
            }
        }
        return NO_COUNT;
    }

    /**
     * tel手机号今天是否还有参加的次数
     * @return 0:没了；1：正常次数；2：会员次数
     */
    public static int hasTelJoinCountToday(String tel, String appId, String openId) {
        PlayGame condition = new PlayGame();
//        condition.setAppId(appId);
//        condition.setOpenId(openId);
        condition.setTel(tel);
        condition.setGameName(GameConstant.GAME_NICK_NAME);

        CompositeResponse<BaseResponse> response = MyRopClient.getRopClient("").buildClientRequest()
                .post(condition, BaseResponse.class, "playGame.getTelJoinCountToday", "1.0");
        if (response.isSuccessful()) {
            BaseResponse baseResponse = response.getSuccessResponse();
            if (baseResponse.getSuccess()) {
                int count = (Integer) baseResponse.getData();
                if (count < GameConstant.MAX_COUNT_OF_TEL_JOIN) {
                    return NORMAL_COUNT;
                } else if (hasJoinCountOfMember(appId, openId, count, GameConstant.MAX_COUNT_OF_TEL_JOIN_MEMBER)) {
                    return MEMBER_COUNT;
                }
            }
        }
        return NO_COUNT;
    }

    public static int hasTelJoinCountToday(String tel, String appId, String openId, String gameName,
                                           int maxTelCount, int maxTelMemberCount) {
        PlayGame condition = new PlayGame();
//        condition.setAppId(appId);
//        condition.setOpenId(openId);
        condition.setTel(tel);
        condition.setGameName(gameName);

        CompositeResponse<BaseResponse> response = MyRopClient.getRopClient("").buildClientRequest()
                .post(condition, BaseResponse.class, "playGame.getTelJoinCountToday", "1.0");
        if (response.isSuccessful()) {
            BaseResponse baseResponse = response.getSuccessResponse();
            if (baseResponse.getSuccess()) {
                int count = (Integer) baseResponse.getData();
                if (count < maxTelCount) {
                    return NORMAL_COUNT;
                } else if (hasJoinCountOfMember(appId, openId, count, maxTelMemberCount)) {
                    return MEMBER_COUNT;
                }
            }
        }
        return NO_COUNT;
    }

    /**
     * 判断是否是会员，是否还有参加次数
     */
    private static boolean hasJoinCountOfMember(String appId, String openId, int count, int maxCount) {
        WechatUser userCondition = new WechatUser();
        userCondition.setAppId(appId);
        userCondition.setOpenId(openId);
        userCondition.setStatus(Constant.STATUS_ENABLE);
        userCondition.setMemberStatus(Constant.MEMBER_USER_SIGN);
        CompositeResponse<BaseResponse> response = MyRopClient.getRopClient("").buildClientRequest()
                .post(userCondition, BaseResponse.class, "wechatUser.listAll", "1.0");
        if (response.isSuccessful()) {
            BaseResponse userResponse = response.getSuccessResponse();
            if (userResponse.getSuccess()) {
                List<LinkedHashMap<String, Object>> dataList = (List<LinkedHashMap<String, Object>>)userResponse.getData();
                if (dataList != null && dataList.size() > 0) {
                    //是会员
                    if (count < maxCount) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 验证提交活动成绩时，签名是否正确
     */
    public static String sign(String score, String appId, String openId, String tel, String secret) {
        StringBuilder sb = new StringBuilder();
        sb.append(secret);
        sb.append("appId").append(appId);
        sb.append("openId").append(openId);
        sb.append("tel").append(tel);
        sb.append("score").append(score);
        sb.append(secret);
        try {
            byte[] sha1Digest = getSHA1Digest(sb.toString());
            return byte2hex(sha1Digest);
        } catch (IOException e) {
            e.printStackTrace();
            logger.warn(e.getMessage());
        }
        return null;
    }

    private static byte[] getSHA1Digest(String data) throws IOException {
        byte[] bytes = null;
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            bytes = md.digest(data.getBytes(Constants.UTF8));
        } catch (GeneralSecurityException gse) {
            throw new IOException(gse.getMessage());
        }
        return bytes;
    }

    /**
     * 二进制转十六进制字符串
     */
    private static String byte2hex(byte[] bytes) {
        StringBuilder sign = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                sign.append("0");
            }
            sign.append(hex.toUpperCase());
        }
        return sign.toString();
    }
}
